﻿//  Copyright (c) 2009 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html
using System;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using System.Linq;
namespace DNA.Mvc.Controllers
{
    ///UNDONE:This class need to implatement IAuthorizationFilter to finish the author.
    /// <summary>
    ///  This Action Filter is specify the Action's access roles managed by Portal
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class SecurityActionAttribute : ActionFilterAttribute
    {
        private string permssionSet = "Default";
        private string title = "";
        private string description = "";
        //private string redirectToController = "Security";
        private string redirectToAction = "";
        private bool throwOnDeny = false;
        private string resBaseName = "perms";
        private string titleResName = "";
        private string descResName = "";
        private string permssionSetResName = "";

        public string PermssionSetResName
        {
            get { return permssionSetResName; }
            set { permssionSetResName = value; }
        }

        public string DescResName
        {
            get { return descResName; }
            set { descResName = value; }
        }

        public string TitleResName
        {
            get { return titleResName; }
            set { titleResName = value; }
        }

        public string ResBaseName
        {
            get { return resBaseName; }
            set { resBaseName = value; }
        }

        public bool ThrowOnDeny
        {
            get { return throwOnDeny; }
            set { throwOnDeny = value; }
        }

        /// <summary>
        /// Gets/Sets the Action to redirect when authorize fail
        /// </summary>
        public string RedirectToAction
        {
            get
            {
                return redirectToAction;
            }
            set { redirectToAction = value; }
        }

        /// <summary>
        /// Init the SecurityActionAccribute class
        /// </summary>
        /// <param name="permissionSetName">Set the PermissionSetName which this Action belongs to.</param>
        /// <param name="permissionTitle">Set the PermissionTitle of this Action</param>
        public SecurityActionAttribute(string permissionSetName, string permissionTitle)
        {
            permssionSet = permissionSetName;
            title = permissionTitle;
        }

        /// <summary>
        /// Init the SecurityActionAccribute class
        /// </summary>
        /// <param name="permissionTitle">Set the PermissionTitle of this Action</param>
        public SecurityActionAttribute(string permissionTitle)
        {
            title = permissionTitle;
        }

        public SecurityActionAttribute(string permissionSetName, string permissionTitle, string permissionDescription)
        {
            permssionSet = permissionSetName;
            title = permissionTitle;
            description = permissionDescription;
        }

        /// <summary>
        /// Get/Sets the Description of the Permission for this Action
        /// </summary>
        public string Description
        {
            get { return description; }
            set { description = value; }
        }

        /// <summary>
        /// Gets/Sets the Title text of the Action
        /// </summary>
        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        /// <summary>
        /// Gets/Sets the PermissionSet name which the security action belongs to
        /// </summary>
        ///<remark>
        ///  If the permission name is not exists Portal will add a new one
        ///</remark>
        public string PermssionSet
        {
            get { return permssionSet; }
            set { permssionSet = value; }
        }

        [Dependency]
        public virtual WebSiteContext Context { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.User.IsWebOwner() || Context.IsAuthorized(filterContext.Controller.GetType(), filterContext.ActionDescriptor.ActionName))
            {
                //要对SiteMapAttribute进行控制
                if (filterContext.ActionDescriptor.IsDefined(typeof(SiteControlPanelAttribute), false))
                {
                    var cpAttrs = (SiteControlPanelAttribute)filterContext.ActionDescriptor.GetCustomAttributes(typeof(SiteControlPanelAttribute), false).First();

                    if (Context.Web!=null && !Context.Web.IsRoot)
                    {
                        if (cpAttrs.ShowInTopSiteOnly)
                        {
                            filterContext.Result = new HttpNotFoundResult();
                        }
                        else
                        {
                            var isAuthorized = Context.IsAuthorized(filterContext.Controller.GetType(), filterContext.ActionDescriptor.ActionName);

                            if (!isAuthorized)
                            {
                                if (Context.Web.Type == (int)WebTypes.Personal)
                                {
                                    if (!filterContext.ActionDescriptor.IsDefined(typeof(MyControlPanelAttribute), false))
                                        filterContext.Result = new HttpNotFoundResult();
                                }
                            }
                        }
                    }
                }
                base.OnActionExecuting(filterContext);
            }
            else
            {
                if (throwOnDeny)
                {
                    throw new AccessDenyException();
                }
                else
                {
                    filterContext.Result = new HttpUnauthorizedResult();
                    base.OnActionExecuting(filterContext);
                }
            }
        }

    }
}
